#include "login_limit.h"

#include <QTimer>
#include <QDate>
#include <QDebug>

#include <ctime>
#include <locale>
#include <iomanip>

#define DEFAULTTIME (15 * 60) // 默认15分钟提示(s)
#define TENMUMTIME (10 * 60) // 10分钟提示(s)
#define FIVEMUMTIME (5 * 60) // 最小5分钟后常驻提示(s)
#define ONEMINUTE (60 * ONESECOND) // 一分钟(ms)
#define ONESECOND 1000 // 一秒钟(ms)

LoginTimeLimit::LoginTimeLimit()
    : m_timer(new QTimer())
    , m_enablePolicy(false)
    , m_locked(false)
{
    m_timer->setInterval(ONEMINUTE); // default 1min
}

LoginTimeLimit::~LoginTimeLimit()
{
}

// 执行策略
int LoginTimeLimit::runPolicy(const QString &config)
{
    // TODO
    return 0;
}

// 执行默认策略(服务端不下发时的执行场景)
int LoginTimeLimit::runDefault()
{
    // TODO: 不下发策略，默认关闭
    m_enablePolicy = false;
    m_remainTime.clear();
    m_timer->stop();

    return 0;
}

/**
 * @brief 更新iam用户登录限制信息
 */
void LoginTimeLimit::setIamInfo()
{
    // TODO: 更新iam中用户限制登录信息，用于离线登录
}

/**
 * @brief 当前是否已经锁屏
 */
bool LoginTimeLimit::isLocked() const
{
    return m_locked;
}

/**
 * @brief 开始锁屏
 */
void LoginTimeLimit::startLockScreen() const
{
}

/**
 * @brief 提示用户信息
 *
 * @param context 显示信息
 * @param timeout 提示驻留时间(s) 0表示常驻
 */
void LoginTimeLimit::showOsdUI(const QString &context, int timeout) const
{
}

/**
 * @brief 隐藏提示信息
 */
void LoginTimeLimit::hideOsdUI() const
{
}

/**
 * @brief 判断是否需要提示用户
 * @return true 需要提示用户
 */
bool LoginTimeLimit::isNeedWarning() const
{
    // 获取当前时间
    const auto &result = std::time(nullptr);
    const auto &current = std::localtime(&result);
    const auto &time = std::put_time(current, "%T");

    // const auto &currentDate = current.date();
    // const auto &currentTime = current.time();
    // const auto &weekday = current->tm_wday;
    // const auto &loginTimes = m_allLoginTimes[weekday];

    // // TODO: loginTimes确保数据按顺序保存的，否则就要判断所有时间段
    // for (const auto &loginTime : loginTimes) {
    //     if (currentTime < loginTime.startTime) {
    //         // 当前时间小于开始时间则认为不允许登录，此时按照需求，提示用户15分钟倒计时
    //         return true;
    //     }

    //     if (currentTime > loginTime.endTime) {
    //         // 当前时间大于结束时间，则判断剩余时间段
    //         continue;
    //     }
    //     return false;
    // }
    // 没有找到对应区间，则需要提示限制登录
    return true;
}

/**
 * @brief 根据时间更新定时器周期
 */
void LoginTimeLimit::updateInterval()
{
    const auto &old = m_timer->interval();
    if ((-1 == m_remainTime.time || FIVEMUMTIME < m_remainTime.time)) {
        // 超出5分钟或者还未到提示用户的时间间隔内，需要将定时间设置为1分钟
        if (ONEMINUTE == old) {
            return;
        }

        m_timer->setInterval(ONEMINUTE);
    } else if (ONESECOND != old) {
        // 5分钟以内提示用户，需要将定时间设置为1S，常驻刷新提示信息
        m_timer->setInterval(ONESECOND);
    }
}

/**
 * @brief 更新剩余时间
 * @param time 策略判断剩余时长(s)
 * @note 在业务处理中time的值只能在-1, <=900
 */
void LoginTimeLimit::updateRemainTime(int time)
{
    assert(time <= 900);
    if (-1 == time) {
        // 剩余时间为-1，表示无需提示用户，清理数据
        m_remainTime.clear();
        return;
    }

    if (DEFAULTTIME != time) {
        // time不是15分钟则表示在正常登录时间内，快到达锁屏的时间
        m_remainTime.time = time;
        return;
    }

    if (-1 == m_remainTime.time) {
        m_remainTime.time = time;
    } else if (FIVEMUMTIME < m_remainTime.time) {
        // 5-15分钟内，定时器1分钟一次，所以减60S
        m_remainTime.time -= 60;
    } else {
        // 5分钟内，定时器1s一次，所以减1
        m_remainTime.time--;
    }
}
